package com.nulldev.util.web.HttpServer3;

import com.nulldev.util.JVM.Arguments;
import com.nulldev.util.VariableAPI.MathUtil;
import com.nulldev.util.io.IOUtils;
import com.nulldev.util.io.throttling.BandwidthThrottler;
import com.nulldev.util.manage.Unimplemented;
import com.nulldev.util.web.HttpServer3.HttpServer3.nCaptchaEnforcementMethod;
import com.nulldev.util.web.HttpServer3.util.HttpServerCOEPPolicy;
import com.nulldev.util.web.HttpServer3.util.HttpServerCOOPPolicy;
import com.nulldev.util.web.HttpServer3.util.HttpServerCORSPolicy;

public class HttpServer3Settings {
	private String serverName = "Default HTTPServer3";

	public String getServerName() {
		return this.serverName;
	}

	public void setServerName(final String sn) {
		if (sn == null || sn.isEmpty())
			return;
		this.serverName = sn;
	}

	/**
	 * HttpServer 3 Extension: NoDDOS! <br>
	 * An experimental plugin that blocks DDOS attempts. <br>
	 * (Will probably be more effective at blocking DOS attacks) <br>
	 * <b>WARNING: Currently experimental. (probably does a better job on DOS
	 * attacks)</b>
	 */
	public boolean enableNoDDOS = Arguments.hasArgument("--HttpServer3.enableNoDDOS");

	/**
	 * HttpServer 3 Extension: STTP. (Secure Text Transfer Protocol) <br>
	 * A secure extension to HTTP that protects data being sent to the user and
	 * being requested. <br>
	 * Required Page Reservations: /sttp_v1/payload_generate (HTTP) <br>
	 * Behaves as an additional protocol, is offered via Alt-Svc. <br>
	 * Implementation status: <b>REMOVED IN 3.0.6</b>
	 */
	@Deprecated
	public boolean enableSTTP;
	/**
	 * HttpServer 3 Extension: Protected Content <br>
	 * A lightweight, non intrusive DRM. (This isn't meant to be a large scale
	 * solution) <br>
	 * Uses OTK. (One Time Tokens, Media is given time until end of request.) <br>
	 * Required Page Reservations: /hpc/hpc_request_token <br>
	 * Required Headers: PC-Content-Token <br>
	 * Levels: <br>
	 * <ul>
	 * <li>L1: Basic, Protected via token [default]</li>
	 * <li>L2: Advanced: Protected via token + Low level encryption</li>
	 * <li>L3: Advanced+: Protected via token + Medium level encryption that is
	 * segmented
	 * </ul>
	 */
	@Unimplemented
	public boolean enablePC;

	/**
	 * HttpServer 3 Security Extension: Body data limits. <br>
	 * Sets the limit to 20MB per client to prevent memory overflow attacks. <br>
	 * <b>ENABLED BY DEFAULT</b>
	 */
	public boolean enforceDataSizeLimit = true;

	/**
	 * Enables SO_LINGER with a value of 5 to prevent overloading the server on
	 * large-scale connections. <br>
	 * Disabled by default since 3.0.6
	 */
	public boolean enableSoLinger = false;

	/**
	 * Enables SO_TIMEOUT with a value of 60 seconds to kill idle sockets and
	 * protect from DoS attacks.<br>
	 * <b>ENABLED BY DEFAULT</b>
	 */
	public boolean enableTimeoutEnforcement = true;

	/**
	 * Enables SO_REUSE on sockets which allows addresses to be reused. <br>
	 * <b>ENABLED BY DEFAULT</b>
	 */
	public boolean enableAddressReuse = true;

	/**
	 * Enables nCaptcha for additional security.
	 */
	public boolean enableNCaptcha = false;

	/**
	 * Tells browsers to allow CORS from all sites. <br>
	 * <b>This should only be used for debugging.</b>
	 */
	public boolean allowCORSFromExternals = false;

	/**
	 * Enables a simple filter for common automated requests by bots.
	 */
	public boolean enableBotAway = false;

	/**
	 * Blocks common web-crawlers from discovering the site.
	 */
	public boolean enableCrawlerBlock = false;

	/**
	 * Enables HTTP STS (HSTS) for extra HTTPS security. <br>
	 * <b>!! EXPERIMENTAL OPTION !!</b>
	 */
	public boolean enableHSTS = false;

	/**
	 * Enables HTTP STS (HSTS) for sub-domains. <br>
	 * Requires <i>enableHSTS</i> to be enabled. <br>
	 * <b>!! EXPERIMENTAL OPTION !!</b>
	 */
	public boolean enableHSTSForSubdomains = false;

	/**
	 * Selects the point where nCaptcha should intervene and request the user to
	 * complete a captcha.
	 */
	public nCaptchaEnforcementMethod nCaptchaMethod = nCaptchaEnforcementMethod.PRE_CONNECT;

	/**
	 * Selects the CORS policy which the server should provide.
	 */
	public HttpServerCORSPolicy corsPolicy = HttpServerCORSPolicy.DISABLED;
	/**
	 * Selects the COEP policy which the server should provide.
	 */
	public HttpServerCOEPPolicy coepPolicy = HttpServerCOEPPolicy.DISABLED;
	/**
	 * Selects the COOP policy which the server should provide.
	 */
	public HttpServerCOOPPolicy coopPolicy = HttpServerCOOPPolicy.DISABLED;

	/**
	 * @returns true if CORS is in use and not set to DISABLED.
	 */
	public boolean hasCORS() {
		return this.corsPolicy != null && this.corsPolicy != HttpServerCORSPolicy.DISABLED;
	}

	/**
	 * @returns true if COEP is in use and not set to DISABLED.
	 */
	public boolean hasCOEP() {
		return this.coepPolicy != null && this.coepPolicy != HttpServerCOEPPolicy.DISABLED;
	}

	/**
	 * @returns true if COOP is in use and not set to DISABLED.
	 */
	public boolean hasCOOP() {
		return this.coopPolicy != null && this.coopPolicy != HttpServerCOOPPolicy.DISABLED;
	}

	/**
	 * If non-null, the entire HttpServer with have a fixed bandwidth, useful for
	 * hosting public things.
	 */
	public BandwidthThrottler bandwidthThrottler = null;

	/**
	 * Enables compat. for legacy clients by providing "Pragma: no-cache" with
	 * NO_CACHE. <br>
	 * Enabled by default.
	 */
	public boolean enableRFC9111Compat = true;

	/**
	 * Enables handling Upgrade-Insecure-Requests on supported environments. <br>
	 * Requires TLS to be setup and enabled. <br>
	 * Enabled by default.
	 */
	public boolean enableHTTPSUpgrade = true;

	/**
	 * The domain to redirect insecure clients to. <br>
	 * Requires <code>VIA_UPGRADE_INSECURE_REQUESTS</code> to be set. <br>
	 * Disabled by default, provide a domain in the format of
	 * <code>https://www.example.com/</code> to enable.
	 * 
	 * @branch rewrite
	 */
	public String httpsUpgradeDomain = null;

	public HTTPSUpgradePolicy httpsUpgradePolicy = HTTPSUpgradePolicy.VIA_CSP;

	public static enum HTTPSUpgradePolicy {
		VIA_UPGRADE_INSECURE_REQUESTS,
		VIA_CSP,
	}

	/**
	 * Enables extra protection against automated systems. <br>
	 * Disabled by default.
	 */
	public boolean enableProxyBotStop = false;

	public ProxyBotStopMode proxyBotStopMode = ProxyBotStopMode.DROP_CONNECTION;

	public static enum ProxyBotStopMode {
		DROP_CONNECTION,
		/** Not my problem(TM) */
		REDIRECT_TO_CF,
	}

	/**
	 * Prints requests by headers and URI. <br>
	 * Intended for debugging. <br>
	 * Disabled by default.
	 */
	public boolean debugPrintRequests = false;

	/**
	 * Prints response headers. <br>
	 * Intended for debugging. <br>
	 * Disabled by default.
	 */
	public boolean debugPrintResponses = false;

	//

	public int http2_maxConcurrentStreamsPerConn = 10;

	/* HTTP 2.0 compat */

	public long maxConcurrentStreamsPerConnection() {
		return MathUtil.clamp(1, 256, this.http2_maxConcurrentStreamsPerConn);
	}

	public long maxHeaderSize() {
		return 1024;
	}

	public int maxHeaderTableSize() {
		return 8192;
	}

	public int patienceThreshold() {
		return 20;
	}

	public boolean noDelay() {
		return true;
	}

	public int outputBufferSize() {
		return IOUtils.MEMORY_ALLOC_BUFFER;
	}
}
